#ifndef GAMELOOP_H
#define GAMELOOP_H


#include "scenewidget.h"
#include "../external/RVO2/src/RVO.h"
#include "gameobject.h"
#include <QObject>
#include <QTimer>

class GameLoop : public QObject
{
    Q_OBJECT
public:
    GameLoop()
    {
        // 创建一个 PreciseTimer, 作用是每帧调用 update 函数
        _timer_loop = new QTimer(this);
        _timer_loop->setTimerType(Qt::PreciseTimer);
        connect(_timer_loop, &QTimer::timeout, this, &GameLoop::update);
        _timer_loop->setInterval(16);

        // 创建一个模拟器
        _simulator = new RVO::RVOSimulator(0.02F, 24.F, 10U, 0.2F, 0.2F, 10.F + 2.F, 100);

        // 创建 5 个游戏对象, 同时与模拟器相互建立连接
        for(int i = 0; i < 5; ++i){
            // 设置随机的初始位置
            RVO::Vector2 position(rand() % _sceneWidget.width(), rand() % _sceneWidget.height());
            _gameObjects.emplace_back(new GameObject);
            _gameObjects.back()->bandSimulator(_simulator, _simulator->addAgent(position));
        }

        // 创建 ui 界面, 并传入游戏对象, 并由 ui 层初始化目标位置
        _sceneWidget.setGameObjects(_gameObjects);
    }
    void start()
    {
        // 显示 ui 界面
        _sceneWidget.show();

        // 启动循环
        _timer_loop->start(16);
    }

    void update()
    {
        // 状态层进行决策
        for(auto& gameObject : _gameObjects){
            gameObject->updateState();
        }

        // RVO2 计算下一帧的位置
        _simulator->doStep();

        // 游戏逻辑层获取并保存当前位置
        for(auto& gameObject : _gameObjects){
            gameObject->syncFromRVO();
        }

        // 最后更新 ui 层
        _sceneWidget.update();
    }
signals:
private:
    QTimer* _timer_loop = nullptr;
    SceneWidget _sceneWidget;
    RVO::RVOSimulator* _simulator = nullptr;
    std::vector<GameObject*> _gameObjects;
};

#endif // GAMELOOP_H
